package uk.co.senab2.photoview2;

import com.ryan.ohos.extension.gesture.GestureDetector;

import ohos.agp.components.Image;
import ohos.agp.utils.RectFloat;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;

/**
 * Provided default implementation of GestureDetector.OnDoubleTapListener, to be overridden with custom behavior, if needed
 * <p>&nbsp;</p>
 * To be used via {@link PhotoViewAttacher#setOnDoubleTapListener(com.ryan.ohos.extension.gesture.GestureDetector.OnDoubleTapListener)}
 */
public class DefaultOnDoubleTapListener implements GestureDetector.OnDoubleTapListener {

    private PhotoViewAttacher photoViewAttacher;

    /**
     * Default constructor.
     *
     * @param photoViewAttacher PhotoViewAttacher to bind to
     */
    public DefaultOnDoubleTapListener(PhotoViewAttacher photoViewAttacher) {
        setPhotoViewAttacher(photoViewAttacher);
    }

    /**
     * Allows to change PhotoViewAttacher within range of single instance.
     *
     * @param newPhotoViewAttacher PhotoViewAttacher to bind to
     */
    public void setPhotoViewAttacher(PhotoViewAttacher newPhotoViewAttacher) {
        this.photoViewAttacher = newPhotoViewAttacher;
    }

    @Override
    public boolean onSingleTapConfirmed(TouchEvent e) {
        if (this.photoViewAttacher == null) {
            return false;
        }
        Image imageView = photoViewAttacher.getImageView();
        PhotoViewAttacher.OnPhotoTapListener onPhotoTapListener = photoViewAttacher.getOnPhotoTapListener();
        if (null != onPhotoTapListener) {
            final RectFloat displayRect = photoViewAttacher.getDisplayRect();
            if (null != displayRect) {
                MmiPoint pointerPosition = e.getPointerPosition(e.getIndex());
                final float x = pointerPosition.getX(), y = pointerPosition.getY();
                // Check to see if the user tapped on the photo
                if (displayRect.isInclude(x, y)) {
                    float xResult = (x - displayRect.left)
                            / displayRect.getWidth();
                    float yResult = (y - displayRect.top)
                            / displayRect.getHeight();
                    onPhotoTapListener.onPhotoTap(imageView, xResult, yResult);
                    return true;
                } else {
                    onPhotoTapListener.onOutsidePhotoTap();
                }
            }
        }
        PhotoViewAttacher.OnViewTapListener onViewTapListener = photoViewAttacher.getOnViewTapListener();
        if (null != onViewTapListener) {
            MmiPoint pointerPosition = e.getPointerPosition(e.getIndex());
            onViewTapListener.onViewTap(imageView, pointerPosition.getX(), pointerPosition.getY());
        }
        return false;
    }

    @Override
    public boolean onDoubleTap(TouchEvent ev) {
        if (photoViewAttacher == null){
            return false;
        }

        try {
            float scale = photoViewAttacher.getScaleFloat();
            MmiPoint pointerPosition = ev.getPointerPosition(ev.getIndex());
            float x = pointerPosition.getX();
            float y = pointerPosition.getY();

            if (scale < photoViewAttacher.getMediumScale()) {
                photoViewAttacher.setScale(photoViewAttacher.getMediumScale(), x, y, true);
            } else if (scale >= photoViewAttacher.getMediumScale() && scale < photoViewAttacher.getMaximumScale()) {
                photoViewAttacher.setScale(photoViewAttacher.getMaximumScale(), x, y, true);
            } else {
                photoViewAttacher.setScale(photoViewAttacher.getMinimumScale(), x, y, true);
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            // Can sometimes happen when getX() and getY() is called
        }

        return true;
    }

    @Override
    public boolean onDoubleTapEvent(TouchEvent e) {
        // Wait for the confirmed onDoubleTap() instead
        return false;
    }

}
